using Monitor.Comm;
using Monitor.Model;

namespace Monitor.Data.Service
{
    /// <summary>
    /// 
    /// </summary>
    public class SystemConfigHelper
    {
        #region 常量
        /// <summary>
        /// Modbus写入配置键
        /// </summary>
        public const string ModbusWriteKey = "ModbusWrite";

        /// <summary>
        /// Modbus读取配置键
        /// </summary>
        public const string ModbusReadKey = "ModbusRead";
        #endregion

        #region 事件
        /// <summary>
        /// 系统配置缓存加载完成事件
        /// </summary>
        public static event EventHandler<CacheLoadedEventArgs> CacheLoaded;
        /// <summary>
        /// 
        /// </summary>
        /// <param name="newKeys"></param>
        public static void OnCacheLoaded(IEnumerable<string> newKeys)
        {
            try
            {
                CacheLoaded?.Invoke(null, new CacheLoadedEventArgs(newKeys));
            }
            catch
            {

            }
        }
        #endregion

        #region 区域信息

        /// <summary>
        /// 界面元素是否显示
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static bool IsShowElement(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
                return true;
            else
                return false;
        }
        #endregion

        #region 配置缓存
        /// <summary>
        /// 配置缓存
        /// </summary>
        private static List<SystemConfig> _cache = new List<SystemConfig>();
        /// <summary>
        /// 配置缓存
        /// </summary>
        public static List<SystemConfig> Cache { get => _cache; }
        /// <summary>
        /// 加载系统配置缓存
        /// </summary>
        /// <returns></returns>
        public static bool LoadCache()
        {
            var ret = DbService.Default.Query<SystemConfig>(null);
            if (ret.Code == DbResultCode.Error)
                return false;

            if (ret.Data?.Count > 0)
            {
                _cache.Clear();
                _cache.AddRange(ret.Data);
                _cache.RemoveAll(p => !SystemConfigHelper.IsShowElement(p.CultrueKey));
                OnCacheLoaded(_cache.Select(p => p.Key));
            }
            return true;
        }
        #endregion

        #region 配置值获取/设置
        /// <summary>
        /// 获取指定键值的参数值
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetValue(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
                return string.Empty;
            try
            {
                var cfg = _cache.Find(p => p.Key == key);
                if (cfg == null)
                    return string.Empty;
                return cfg.Value ?? string.Empty;
            }
            catch
            {
                return string.Empty;
            }
        }
        /// <summary>
        /// 获取指定键值的参数值并转换指定基础类型（string/int/double/enum）
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="key"></param>
        /// <param name="defaultValue"></param>
        /// <returns></returns>
        public static T1 GetValue<T1>(string key, T1 defaultValue)
        {
            if (string.IsNullOrWhiteSpace(key))
                return defaultValue;
            try
            {
                var cfg = _cache.Find(p => p.Key == key);
                if (cfg == null)
                    return defaultValue;
                var type = typeof(T1);
                if (type.IsEnum && cfg.ValueType == enumConfigValueType.Enum)
                {
                    if (int.TryParse(cfg.Value, out int intVal) && Enum.IsDefined(type, intVal))
                        return (T1)Enum.ToObject(type, intVal);
                    else
                        return defaultValue;
                }
                else
                {
                    return (T1)Convert.ChangeType(cfg.Value, typeof(T1));
                }
            }
            catch
            {
                return defaultValue;
            }
        }
        /// <summary>
        /// 获取指定键值的Data数据
        /// </summary>
        /// <param name="key"></param>
        /// <returns></returns>
        public static string GetData(string key)
        {
            if (string.IsNullOrWhiteSpace(key))
                return string.Empty;
            try
            {
                var cfg = _cache.Find(p => p.Key == key);
                if (cfg == null)
                    return string.Empty;
                return cfg.Data ?? string.Empty;
            }
            catch
            {
                return string.Empty;
            }
        }

        public static T GetData<T>(string key, T defaultValue)
        {
            if (string.IsNullOrWhiteSpace(key))
                return defaultValue;
            try
            {
                var cfg = _cache.Find(p => p.Key == key);
                if (cfg == null || cfg.Value != "{JSON}")
                    return defaultValue;
                return cfg.Data.ToJsonObject<T>();
            }
            catch
            {
                return defaultValue;
            }
        }

        /// <summary>
        /// 设置系统参数值
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool SetValue(string key, string value)
        {
            if (string.IsNullOrWhiteSpace(key))
                return false;

            var ret = DbService.Default.CreateDb().Update<SystemConfig>().Set(new { Value = value }, p => p.Key == key).Execute();
            if (ret.Code == DbResultCode.Error)
                return false;

            return true;
        }
        /// <summary>
        /// 设置系统参数值和数据
        /// </summary>
        /// <param name="key"></param>
        /// <param name="value"></param>
        /// <param name="data"></param>
        /// <returns></returns>
        public static bool SetData(string key, string value, string data)
        {
            if (string.IsNullOrWhiteSpace(key))
                return false;

            var ret = DbService.Default.CreateDb().Update<SystemConfig>().Set(new { Value = value, Data = data }, p => p.Key == key).Execute();
            if (ret.Code == DbResultCode.Error)
                return false;

            return true;
        }
        #endregion

        #region 配置
        /// <summary>
        /// Modbus写入
        /// </summary>
        public static string ModbusWrite => GetValue(ModbusWriteKey);

        /// <summary>
        /// Modbus读取
        /// </summary>
        public static string ModbusRead => GetValue(ModbusReadKey);
        #endregion
    }

    /// <summary>
    /// 
    /// </summary>
    public class CacheLoadedEventArgs : EventArgs
    {
        /// <summary>
        /// 
        /// </summary>
        /// <param name="newKeys"></param>
        public CacheLoadedEventArgs(IEnumerable<string> newKeys)
        {
            this.NewKeys = newKeys?.ToArray();
        }

        /// <summary>
        /// 本次加载更新缓存的键值集合
        /// </summary>
        public string[] NewKeys { get; }

    }
}
